home *** CD-ROM | disk | FTP | other *** search
/ PC Open 107 / PC Open 107 CD 1.bin / CD1 / INTERNET / COPIA SITI / Getleft / getleft-setup-notcl.exe / {app} / scripts / tablelistConfig.tcl < prev    next >
Encoding:
Text File  |  2003-12-29  |  62.0 KB  |  2,301 lines

  1. #==============================================================================
  2. # Contains private configuration procedures for tablelist widgets.
  3. #
  4. # Copyright (c) 2000-2004  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
  5. #==============================================================================
  6.  
  7. #------------------------------------------------------------------------------
  8. # tablelist::extendConfigSpecs
  9. #
  10. # Extends the elements of the array configSpecs.
  11. #------------------------------------------------------------------------------
  12. proc tablelist::extendConfigSpecs {} {
  13.     variable helpLabel
  14.     variable configSpecs
  15.     variable winSys
  16.  
  17.     #
  18.     # Append the default values of the configuration options
  19.     # of a temporary, invisible listbox widget to the values
  20.     # of the corresponding elements of the array configSpecs
  21.     #
  22.     set helpListbox .__helpListbox
  23.     for {set n 0} {[winfo exists $helpListbox]} {incr n} {
  24.     set helpListbox .__helpListbox$n
  25.     }
  26.     listbox $helpListbox
  27.     foreach configSet [$helpListbox configure] {
  28.     if {[llength $configSet] != 2} {
  29.         set opt [lindex $configSet 0]
  30.         if {[info exists configSpecs($opt)]} {
  31.         lappend configSpecs($opt) [lindex $configSet 3]
  32.         }
  33.     }
  34.     }
  35.     destroy $helpListbox
  36.  
  37.     #
  38.     # Append the default values of some configuration options
  39.     # of an invisible label widget to the values of the
  40.     # corresponding -label* elements of the array configSpecs
  41.     #
  42.     set helpLabel .__helpLabel
  43.     for {set n 0} {[winfo exists $helpLabel]} {incr n} {
  44.     set helpLabel .__helpLabel$n
  45.     }
  46.     label $helpLabel
  47.     foreach optTail {font height} {
  48.     set configSet [$helpLabel config -$optTail]
  49.     lappend configSpecs(-label$optTail) [lindex $configSet 3]
  50.     }
  51.     if {[catch {$helpLabel config -state disabled}] == 0 &&
  52.     [catch {$helpLabel config -state normal}] == 0 &&
  53.     [catch {$helpLabel config -disabledforeground} configSet] == 0} {
  54.     lappend configSpecs(-labeldisabledforeground) [lindex $configSet 3]
  55.     } else {
  56.     unset configSpecs(-labeldisabledforeground)
  57.     }
  58.     if {[string compare $winSys win32] == 0} {
  59.     lappend configSpecs(-labelpady) 0
  60.     } else {
  61.     set configSet [$helpLabel config -pady]
  62.     lappend configSpecs(-labelpady) [lindex $configSet 3]
  63.     }
  64.  
  65.     #
  66.     # Steal the default values of some configuration
  67.     # options from a temporary, invisible button widget
  68.     #
  69.     set helpButton .__helpButton
  70.     for {set n 0} {[winfo exists $helpButton]} {incr n} {
  71.     set helpButton .__helpButton$n
  72.     }
  73.     button $helpButton
  74.     foreach opt {-disabledforeground -state} {
  75.     set configSet [$helpButton config $opt]
  76.     lappend configSpecs($opt) [lindex $configSet 3]
  77.     }
  78.     foreach optTail {background foreground} {
  79.     set configSet [$helpButton config -$optTail]
  80.     lappend configSpecs(-label$optTail) [lindex $configSet 3]
  81.     }
  82.     if {[string compare $winSys classic] == 0 ||
  83.     [string compare $winSys aqua] == 0} {
  84.     lappend configSpecs(-labelborderwidth) 1
  85.     } else {
  86.     set configSet [$helpButton config -borderwidth]
  87.     lappend configSpecs(-labelborderwidth) [lindex $configSet 3]
  88.     }
  89.     destroy $helpButton
  90.  
  91.     #
  92.     # Extend the remaining elements of the array configSpecs
  93.     #
  94.     lappend configSpecs(-activestyle)        underline
  95.     lappend configSpecs(-arrowcolor)        {}
  96.     lappend configSpecs(-arrowdisabledcolor)    {}
  97.     lappend configSpecs(-columns)        {}
  98.     lappend configSpecs(-editendcommand)    {}
  99.     lappend configSpecs(-editstartcommand)    {}
  100.     lappend configSpecs(-incrarrowtype)        up
  101.     lappend configSpecs(-labelcommand)        {}
  102.     lappend configSpecs(-labelrelief)        raised
  103.     lappend configSpecs(-listvariable)        {}
  104.     lappend configSpecs(-movablecolumns)    0
  105.     lappend configSpecs(-movecolumncursor)    icon
  106.     lappend configSpecs(-resizablecolumns)    1
  107.     lappend configSpecs(-resizecursor)        sb_h_double_arrow
  108.     lappend configSpecs(-showarrow)        1
  109.     lappend configSpecs(-showlabels)        1
  110.     lappend configSpecs(-showseparators)    0
  111.     lappend configSpecs(-snipstring)        ...
  112.     lappend configSpecs(-sortcommand)        {}
  113.     lappend configSpecs(-stretch)        {}
  114.     lappend configSpecs(-stripebackground)    {}
  115.     lappend configSpecs(-stripeforeground)    {}
  116.     lappend configSpecs(-stripeheight)        1
  117.     lappend configSpecs(-targetcolor)        black
  118. }
  119.  
  120. #------------------------------------------------------------------------------
  121. # tablelist::doConfig
  122. #
  123. # Applies the value val of the configuration option opt to the tablelist widget
  124. # win.
  125. #------------------------------------------------------------------------------
  126. proc tablelist::doConfig {win opt val} {
  127.     variable helpLabel
  128.     variable configSpecs
  129.     upvar ::tablelist::ns${win}::data data
  130.  
  131.     #
  132.     # Apply the value to the widget(s) corresponding to the given option
  133.     #
  134.     switch [lindex $configSpecs($opt) 2] {
  135.     c {
  136.         #
  137.         # Apply the value to all children and save the
  138.         # properly formatted value of val in data($opt)
  139.         #
  140.         foreach w [winfo children $win] {
  141.         if {[regexp {^(body|hdr|sep[0-9]+)$} [winfo name $w]]} {
  142.             $w configure $opt $val
  143.         }
  144.         }
  145.         $data(hdrTxt) configure $opt $val
  146.         $data(hdrLbl) configure $opt $val
  147.         foreach w [winfo children $data(hdrTxtFr)] {
  148.         $w configure $opt $val
  149.         foreach c [winfo children $w] {
  150.             $c configure $opt $val
  151.         }
  152.         }
  153.         set data($opt) [$data(hdrLbl) cget $opt]
  154.     }
  155.  
  156.     b {
  157.         #
  158.         # Apply the value to the body text widget and save
  159.         # the properly formatted value of val in data($opt)
  160.         #
  161.         set w $data(body)
  162.         $w configure $opt $val
  163.         set data($opt) [$w cget $opt]
  164.  
  165.         switch -- $opt {
  166.         -background {
  167.             #
  168.             # Apply the value to the frame (because of
  169.             # the shadow colors of its 3-D border), to
  170.             # the separators, and to the "disabled" tag
  171.             #
  172.             $win configure $opt $val
  173.             foreach c [winfo children $win] {
  174.             if {[regexp {^sep[0-9]+$} [winfo name $c]]} {
  175.                 $c configure $opt $val
  176.             }
  177.             }
  178.             $w tag configure disabled $opt $val
  179.         }
  180.         -font {
  181.             #
  182.             # Apply the value to the listbox child, rebuild the lists
  183.             # of the column fonts and tag names, configure the edit
  184.             # window if present, set up and adjust the columns, and
  185.             # make sure the items will be redisplayed at idle time
  186.             #
  187.             $data(lb) configure $opt $val
  188.             set data(charWidth) [font measure $val -displayof $win 0]
  189.             makeColFontAndTagLists $win
  190.             if {$data(editRow) >= 0} {
  191.             variable editWin
  192.             set name $data($data(editCol)-editwindow)
  193.             set item [lindex $data(itemList) $data(editRow)]
  194.             set key [lindex $item end]
  195.             catch {
  196.                 $data(bodyFrEd) configure $editWin($name-fontOpt) \
  197.                 [cellFont $win $key $data(editCol)]
  198.             }
  199.             }
  200.             for {set col 0} {$col < $data(colCount)} {incr col} {
  201.             if {$data($col-maxwidth) > 0} {
  202.                 set data($col-maxPixels) \
  203.                 [charsToPixels $win $val $data($col-maxwidth)]
  204.             }
  205.             }
  206.             setupColumns $win $data(-columns) 0
  207.             adjustColumns $win allCols 1
  208.             redisplayWhenIdle $win
  209.         }
  210.         -foreground {
  211.             #
  212.             # Apply the value to the "disabled" tag if needed
  213.             #
  214.             if {[string compare $data(-disabledforeground) ""] == 0} {
  215.             $w tag configure disabled $opt $val
  216.             }
  217.         }
  218.         }
  219.     }
  220.  
  221.     h {
  222.         #
  223.         # Apply the value to the header text widget and save
  224.         # the properly formatted value of val in data($opt)
  225.         #
  226.         set w $data(hdrTxt)
  227.         $w configure $opt $val
  228.         set data($opt) [$w cget $opt]
  229.     }
  230.  
  231.     l {
  232.         #
  233.         # Apply the value to all not individually configured labels
  234.         # and save the properly formatted value of val in data($opt)
  235.         #
  236.         set optTail [string range $opt 6 end]    ;# remove the -label
  237.         $data(hdrLbl) configure -$optTail $val
  238.         for {set col 0} {$col < $data(colCount)} {incr col} {
  239.         set w $data(hdrTxtFrLbl)$col
  240.         if {![info exists data($col$opt)]} {
  241.             configLabel $w -$optTail $val
  242.         }
  243.         }
  244.         set data($opt) [$data(hdrLbl) cget -$optTail]
  245.  
  246.         switch -- $opt {
  247.         -labelbackground {
  248.             #
  249.             # Apply the value to the children of the header frame and
  250.             # conditionally both to the children of the labels (if
  251.             # any) and to the canvas displaying an up- or down-arrow
  252.             #
  253.             $data(hdrTxt) configure -$optTail $val
  254.             for {set col 0} {$col < $data(colCount)} {incr col} {
  255.             set w $data(hdrTxtFrLbl)$col
  256.             if {![info exists data($col$opt)]} {
  257.                 foreach c [winfo children $w] {
  258.                 $c configure -$optTail $val
  259.                 }
  260.             }
  261.             }
  262.             if {$data(arrowCol) >= 0 &&
  263.             ![info exists data($data(arrowCol)$opt)]} {
  264.             configCanvas $win
  265.             }
  266.         }
  267.         -labelborderwidth {
  268.             #
  269.             # Adjust the columns (including
  270.             # the height of the header frame)
  271.             #
  272.             adjustColumns $win allLabels 1
  273.         }
  274.         -labeldisabledforeground {
  275.             #
  276.             # Apply the value to the children of the labels (if any)
  277.             #
  278.             foreach w [winfo children $data(hdrTxtFr)] {
  279.             foreach c [winfo children $w] {
  280.                 $c configure $opt $val
  281.             }
  282.             }
  283.         }
  284.         -labelfont {
  285.             #
  286.             # Conditionally apply the value to the children of
  287.             # the labels (if any), conditionally resize the canvas
  288.             # displaying an up- or down-arrow, and adjust the
  289.             # columns (including the height of the header frame)
  290.             #
  291.             for {set col 0} {$col < $data(colCount)} {incr col} {
  292.             set w $data(hdrTxtFrLbl)$col
  293.             if {![info exists data($col$opt)]} {
  294.                 foreach c [winfo children $w] {
  295.                 $c configure -$optTail $val
  296.                 }
  297.             }
  298.             }
  299.             if {$data(arrowCol) >= 0 &&
  300.             ![info exists data($data(arrowCol)$opt)]} {
  301.             configCanvas $win
  302.             drawArrows $win
  303.             }
  304.             adjustColumns $win allLabels 1
  305.         }
  306.         -labelforeground {
  307.             #
  308.             # Conditionally apply the value to
  309.             # the children of the labels (if any)
  310.             #
  311.             for {set col 0} {$col < $data(colCount)} {incr col} {
  312.             set w $data(hdrTxtFrLbl)$col
  313.             if {![info exists data($col$opt)]} {
  314.                 foreach c [winfo children $w] {
  315.                 $c configure -$optTail $val
  316.                 }
  317.             }
  318.             }
  319.         }
  320.         -labelheight -
  321.         -labelpady {
  322.             #
  323.             # Adjust the height of the header frame
  324.             #
  325.             adjustHeaderHeight $win
  326.         }
  327.         }
  328.     }
  329.  
  330.     f {
  331.         #
  332.         # Apply the value to the frame and save the
  333.         # properly formatted value of val in data($opt)
  334.         #
  335.         $win configure $opt $val
  336.         set data($opt) [$win cget $opt]
  337.     }
  338.  
  339.     w {
  340.         switch -- $opt {
  341.         -activestyle {
  342.             #
  343.             # Configure the "active" tag and save the
  344.             # properly formatted value of val in data($opt)
  345.             #
  346.             variable activeStyles
  347.             set val [mwutil::fullOpt "active style" $val $activeStyles]
  348.             set w $data(body)
  349.             switch $val {
  350.             frame {
  351.                 $w tag configure active -relief solid -underline 0
  352.             }
  353.             none {
  354.                 $w tag configure active -relief flat -underline 0
  355.             }
  356.             underline {
  357.                 $w tag configure active -relief flat -underline 1
  358.             }
  359.             }
  360.             set data($opt) $val
  361.         }
  362.         -arrowcolor {
  363.             #
  364.             # Set the color of the normal arrow and save the
  365.             # properly formatted value of val in data($opt)
  366.             #
  367.             set data($opt) [fillArrow $data(hdrTxtFrCanv) normal $val]
  368.         }
  369.         -arrowdisabledcolor {
  370.             #
  371.             # Set the color of the disabled arrow and save the
  372.             # properly formatted value of val in data($opt)
  373.             #
  374.             set data($opt) [fillArrow $data(hdrTxtFrCanv) disabled $val]
  375.         }
  376.         -columns {
  377.             #
  378.             # Set up and adjust the columns, rebuild
  379.             # the lists of the column fonts and tag
  380.             # names, and redisplay the items
  381.             #
  382.             setupColumns $win $val 1
  383.             adjustColumns $win allCols 1
  384.             makeColFontAndTagLists $win
  385.             redisplay $win
  386.         }
  387.         -disabledforeground {
  388.             #
  389.             # Configure the "disabled" tag in the body text widget and
  390.             # save the properly formatted value of val in data($opt)
  391.             #
  392.             set w $data(body)
  393.             if {[string compare $val ""] == 0} {
  394.             $w tag configure disabled -fgstipple gray50 \
  395.                 -foreground $data(-foreground)
  396.             set data($opt) ""
  397.             } else {
  398.             $w tag configure disabled -fgstipple "" \
  399.                 -foreground $val
  400.             set data($opt) [$w tag cget disabled -foreground]
  401.             }
  402.         }
  403.         -editendcommand -
  404.         -editstartcommand -
  405.         -labelcommand -
  406.         -selectmode -
  407.         -sortcommand {
  408.             set data($opt) $val
  409.         }
  410.         -exportselection {
  411.             #
  412.             # Save the boolean value specified by val in
  413.             # data($opt).  In addition, if the selection is
  414.             # exported and there are any selected rows in the
  415.             # widget then make win the new owner of the PRIMARY
  416.             # selection and register a callback to be invoked
  417.             # when it loses ownership of the PRIMARY selection
  418.             #
  419.             set data($opt) [expr {$val ? 1 : 0}]
  420.             if {$val &&
  421.             [llength [$data(body) tag nextrange select 1.0]] != 0} {
  422.             selection own -command \
  423.                 [list ::tablelist::lostSelection $win] $win
  424.             }
  425.         }
  426.         -height {
  427.             #
  428.             # Adjust the heights of the body text widget
  429.             # and of the listbox child, and save the
  430.             # properly formatted value of val in data($opt)
  431.             #
  432.             set val [format %d $val]    ;# integer check with error msg
  433.             if {$val <= 0} {
  434.             $data(body) configure $opt $data(itemCount)
  435.             $data(lb) configure $opt $data(itemCount)
  436.             } else {
  437.             $data(body) configure $opt $val
  438.             $data(lb) configure $opt $val
  439.             }
  440.             set data($opt) $val
  441.         }
  442.         -incrarrowtype {
  443.             #
  444.             # Save the properly formatted value of val
  445.             # in data($opt) and draw the arrows if
  446.             # the canvas widget is presently mapped
  447.             #
  448.             variable arrowTypes
  449.             set data($opt) \
  450.             [mwutil::fullOpt "arrow type" $val $arrowTypes]
  451.             if {$data(arrowCol) >= 0} {
  452.             drawArrows $win
  453.             }
  454.         }
  455.         -listvariable {
  456.             #
  457.             # Associate val as list variable with the
  458.             # given widget and save it in data($opt)
  459.             #
  460.             makeListVar $win $val
  461.             set data($opt) $val
  462.             if {[string compare $val ""] == 0} {
  463.             set data(hasListVar) 0
  464.             } else {
  465.             set data(hasListVar) 1
  466.             }
  467.         }
  468.         -movablecolumns -
  469.         -resizablecolumns {
  470.             #
  471.             # Save the boolean value specified by val in data($opt)
  472.             #
  473.             set data($opt) [expr {$val ? 1 : 0}]
  474.         }
  475.         -movecolumncursor -
  476.         -resizecursor {
  477.             #
  478.             # Save the properly formatted value of val in data($opt)
  479.             #
  480.             $helpLabel configure -cursor $val
  481.             set data($opt) [$helpLabel cget -cursor]
  482.         }
  483.         -selectbackground -
  484.         -selectforeground {
  485.             #
  486.             # Configure the "select" tag in the body text widget
  487.             # and save the properly formatted value of val in
  488.             # data($opt).  Don't use the built-in "sel" tag
  489.             # because on Windows the selection in a text widget only
  490.             # becomes visible when the window gets the input focus.
  491.             #
  492.             set w $data(body)
  493.             set optTail [string range $opt 7 end] ;# remove the -select
  494.             $w tag configure select -$optTail $val
  495.             set data($opt) [$w tag cget select -$optTail]
  496.         }
  497.         -selectborderwidth {
  498.             #
  499.             # Configure the "select" tag in the body text widget
  500.             # and save the properly formatted value of val in
  501.             # data($opt).  Don't use the built-in "sel" tag
  502.             # because on Windows the selection in a text widget only
  503.             # becomes visible when the window gets the input focus.
  504.             # In addition, adjust the line spacing accordingly and
  505.             # apply the value to the listbox child, too.
  506.             #
  507.             set w $data(body)
  508.             set optTail [string range $opt 7 end] ;# remove the -select
  509.             $w tag configure select -$optTail $val
  510.             set data($opt) [$w tag cget select -$optTail]
  511.             if {$val < 0} {
  512.             set val 0
  513.             }
  514.             $w configure -spacing1 $val -spacing3 [expr {$val + 1}]
  515.             $data(lb) configure $opt $val
  516.         }
  517.         -setgrid {
  518.             #
  519.             # Apply the value to the listbox child and save
  520.             # the properly formatted value of val in data($opt)
  521.             #
  522.             $data(lb) configure $opt $val
  523.             set data($opt) [$data(lb) cget $opt]
  524.         }
  525.         -showarrow {
  526.             #
  527.             # Save the boolean value specified by val in
  528.             # data($opt) and conditionally unmanage the
  529.             # canvas displaying an up- or down-arrow
  530.             #
  531.             set data($opt) [expr {$val ? 1 : 0}]
  532.             if {!$data($opt) && $data(arrowCol) >= 0} {
  533.             place forget $data(hdrTxtFrCanv)
  534.             set oldArrowCol $data(arrowCol)
  535.             set data(arrowCol) -1
  536.             adjustColumns $win l$oldArrowCol 1
  537.             }
  538.         }
  539.         -showlabels {
  540.             #
  541.             # Save the boolean value specified by val in data($opt)
  542.             # and adjust the height of the header frame
  543.             #
  544.             set data($opt) [expr {$val ? 1 : 0}]
  545.             adjustHeaderHeight $win
  546.         }
  547.         -showseparators {
  548.             #
  549.             # Save the boolean value specified by val in data($opt),
  550.             # and create or destroy the separators if needed
  551.             #
  552.             set oldVal $data($opt)
  553.             set data($opt) [expr {$val ? 1 : 0}]
  554.             if {!$oldVal && $data($opt)} {
  555.             createSeps $win
  556.             } elseif {$oldVal && !$data($opt)} {
  557.             foreach w [winfo children $win] {
  558.                 if {[regexp {^sep[0-9]+$} [winfo name $w]]} {
  559.                 destroy $w
  560.                 }
  561.             }
  562.             }
  563.         }
  564.         -snipstring {
  565.             #
  566.             # Save val in data($opt), adjust the columns, and make
  567.             # sure the items will be redisplayed at idle time
  568.             #
  569.             set data($opt) $val
  570.             adjustColumns $win {} 0
  571.             redisplayWhenIdle $win
  572.         }
  573.         -state {
  574.             #
  575.             # Apply the value to all labels and their children (if
  576.             # any), as well as to the edit window (if present),
  577.             # raise the corresponding arrow in the canvas, add/
  578.             # remove the "disabled" tag to/from the contents of
  579.             # the body text widget, configure the borderwidth
  580.             # of the "active" and "select" tags, and save the
  581.             # properly formatted value of val in data($opt)
  582.             #
  583.             variable states
  584.             set val [mwutil::fullOpt "state" $val $states]
  585.             catch {
  586.             foreach w [winfo children $data(hdrTxtFr)] {
  587.                 $w configure $opt $val
  588.                 foreach c [winfo children $w] {
  589.                 $c configure $opt $val
  590.                 }
  591.             }
  592.             }
  593.             if {$data(editRow) >= 0} {
  594.             catch {$data(bodyFrEd) configure $opt $val}
  595.             }
  596.             raiseArrow $data(hdrTxtFrCanv) $val
  597.             set w $data(body)
  598.             switch $val {
  599.             disabled {
  600.                 $w tag add disabled 1.0 end
  601.                 $w tag configure active -borderwidth 0
  602.                 $w tag configure select -borderwidth 0
  603.                 set data(isDisabled) 1
  604.             }
  605.             normal {
  606.                 $w tag remove disabled 1.0 end
  607.                 $w tag configure active -borderwidth 1
  608.                 $w tag configure select -borderwidth \
  609.                     $data(-selectborderwidth)
  610.                 set data(isDisabled) 0
  611.             }
  612.             }
  613.             set data($opt) $val
  614.         }
  615.         -stretch {
  616.             #
  617.             # Save the properly formatted value of val in
  618.             # data($opt) and stretch the stretchable columns
  619.             #
  620.             if {[string first $val all] == 0} {
  621.             set data($opt) all
  622.             } else {
  623.             set data($opt) $val
  624.             sortStretchableColList $win
  625.             }
  626.             set data(forceAdjust) 1
  627.             stretchColumnsWhenIdle $win
  628.         }
  629.         -stripebackground -
  630.         -stripeforeground {
  631.             #
  632.             # Configure the "stripe" tag in the body text
  633.             # widget, save the properly formatted value of val
  634.             # in data($opt), and draw the stripes if necessary
  635.             #
  636.             set w $data(body)
  637.             set optTail [string range $opt 7 end] ;# remove the -stripe
  638.             $w tag configure stripe -$optTail $val
  639.             set data($opt) [$w tag cget stripe -$optTail]
  640.             makeStripesWhenIdle $win
  641.         }
  642.         -stripeheight {
  643.             #
  644.             # Save the properly formatted value of val in
  645.             # data($opt) and draw the stripes if necessary
  646.             #
  647.             set val [format %d $val]    ;# integer check with error msg
  648.             set data($opt) $val
  649.             makeStripesWhenIdle $win
  650.         }
  651.         -targetcolor {
  652.             #
  653.             # Set the color of the header gap and save the
  654.             # properly formatted value of val in data($opt)
  655.             #
  656.             $data(hdrGap) configure -background $val
  657.             set data($opt) [$data(hdrGap) cget -background]
  658.         }
  659.         -width {
  660.             #
  661.             # Adjust the widths of the body text widget,
  662.             # header frame, and listbox child, and save the
  663.             # properly formatted value of val in data($opt)
  664.             #
  665.             set val [format %d $val]    ;# integer check with error msg
  666.             $data(body) configure $opt $val
  667.             if {$val <= 0} {
  668.             $data(hdr) configure $opt $data(hdrPixels)
  669.             $data(lb) configure $opt \
  670.                   [expr {$data(hdrPixels) / $data(charWidth)}]
  671.             } else {
  672.             $data(hdr) configure $opt 0
  673.             $data(lb) configure $opt $val
  674.             }
  675.             set data($opt) $val
  676.         }
  677.         }
  678.     }
  679.     }
  680. }
  681.  
  682. #------------------------------------------------------------------------------
  683. # tablelist::doColConfig
  684. #
  685. # Applies the value val of the column configuration option opt to the col'th
  686. # column of the tablelist widget win.
  687. #------------------------------------------------------------------------------
  688. proc tablelist::doColConfig {col win opt val} {
  689.     upvar ::tablelist::ns${win}::data data
  690.  
  691.     switch -- $opt {
  692.     -align {
  693.         #
  694.         # Set up and adjust the columns, and make sure
  695.         # the items will be redisplayed at idle time
  696.         #
  697.         set idx [expr {3*$col + 2}]
  698.         setupColumns $win [lreplace $data(-columns) $idx $idx $val] 0
  699.         adjustColumns $win {} 0
  700.         redisplayWhenIdle $win
  701.     }
  702.  
  703.     -background -
  704.     -foreground {
  705.         set w $data(body)
  706.         set tag $col$opt
  707.         if {[string compare $val ""] == 0} {
  708.         if {[info exists data($tag)]} {
  709.             $w tag delete $tag
  710.             unset data($tag)
  711.         }
  712.         } else {
  713.         #
  714.         # Configure the tag $tag in the body text widget
  715.         #
  716.         $w tag configure $tag $opt $val
  717.         $w tag raise $tag stripe
  718.  
  719.         if {!$data($col-hide)} {
  720.             #
  721.             # Apply the tag to the elements of the given column
  722.             #
  723.             for {set idx 0; set line 1} {$idx < $data(itemCount)} \
  724.             {incr idx; incr line} {
  725.             if {[lsearch -exact [$w tag names $line.0] select]
  726.                 < 0} {
  727.                 findCellTabs $win $line $col tabIdx1 tabIdx2
  728.                 $w tag add $tag $tabIdx1 $tabIdx2+1c
  729.             }
  730.             }
  731.         }
  732.  
  733.         #
  734.         # Save the properly formatted value of val in data($tag)
  735.         #
  736.         set data($tag) [$w tag cget $tag $opt]
  737.         }
  738.  
  739.         #
  740.         # Rebuild the lists of the column fonts and tag names
  741.         #
  742.         makeColFontAndTagLists $win
  743.     }
  744.  
  745.     -editable -
  746.     -resizable {
  747.         #
  748.         # Save the boolean value specified by val in data($col$opt)
  749.         #
  750.         set data($col$opt) [expr {$val ? 1 : 0}]
  751.     }
  752.  
  753.     -editwindow {
  754.         variable editWin
  755.         if {[regexp {^(entry|checkbutton)$} $val] ||
  756.         ($::tk_version >= 8.4 && [string compare $val spinbox] == 0) ||
  757.         [info exists editWin($val-creationCmd)]} {
  758.         set data($col$opt) $val
  759.         } else {
  760.         return -code error "name \"$val\" is not registered\
  761.                     for interactive cell editing"
  762.         }
  763.     }
  764.  
  765.     -font {
  766.         set w $data(body)
  767.         set tag $col$opt
  768.         if {[string compare $val ""] == 0} {
  769.         if {[info exists data($tag)]} {
  770.             $w tag delete $tag
  771.             unset data($tag)
  772.         }
  773.         } else {
  774.         #
  775.         # Configure the tag $tag in the body text widget
  776.         #
  777.         $w tag configure $tag $opt $val
  778.         $w tag lower $tag
  779.  
  780.         if {!$data($col-hide)} {
  781.             #
  782.             # Apply the tag to the elements of the given column
  783.             #
  784.             for {set idx 0; set line 1} {$idx < $data(itemCount)} \
  785.             {incr idx; incr line} {
  786.             findCellTabs $win $line $col tabIdx1 tabIdx2
  787.             $w tag add $tag $tabIdx1 $tabIdx2+1c
  788.             }
  789.         }
  790.  
  791.         #
  792.         # Save the properly formatted value of val in data($tag)
  793.         #
  794.         set data($tag) [$w tag cget $tag $opt]
  795.         }
  796.  
  797.         #
  798.         # Rebuild the lists of the column fonts and tag names
  799.         #
  800.         makeColFontAndTagLists $win
  801.  
  802.         #
  803.         # Adjust the columns, and make sure the items
  804.         # will be redisplayed at idle time if needed
  805.         #
  806.         adjustColumns $win $col 1
  807.         set pixels [lindex $data(colList) [expr {2*$col}]]
  808.         if {$pixels == 0} {            ;# convention: dynamic width
  809.         if {$data($col-maxPixels) > 0 &&
  810.             $data($col-reqPixels) > $data($col-maxPixels)} {
  811.             set pixels $data($col-maxPixels)
  812.         }
  813.         }
  814.         if {$pixels != 0} {
  815.         redisplayWhenIdle $win
  816.         }
  817.  
  818.         if {$col == $data(editCol)} {
  819.         #
  820.         # Configure the edit window
  821.         #
  822.         variable editWin
  823.         set name $data($col-editwindow)
  824.         set item [lindex $data(itemList) $data(editRow)]
  825.         set key [lindex $item end]
  826.         catch {
  827.             $data(bodyFrEd) configure $editWin($name-fontOpt) \
  828.             [cellFont $win $key $col]
  829.         }
  830.         }
  831.     }
  832.  
  833.     -formatcommand {
  834.         if {[string compare $val ""] == 0} {
  835.         if {[info exists data($col$opt)]} {
  836.             unset data($col$opt)
  837.         }
  838.         set fmtCmdFlag 0
  839.         } else {
  840.         set data($col$opt) $val
  841.         set fmtCmdFlag 1
  842.         }
  843.  
  844.         #
  845.         # Update the corresponding element of the list data(fmtCmdFlagList)
  846.         #
  847.         set data(fmtCmdFlagList) \
  848.         [lreplace $data(fmtCmdFlagList) $col $col $fmtCmdFlag]
  849.  
  850.         #
  851.         # Adjust the columns and make sure the
  852.         # items will be redisplayed at idle time
  853.         #
  854.         adjustColumns $win $col 1
  855.         redisplayWhenIdle $win
  856.     }
  857.  
  858.     -hide {
  859.         #
  860.         # Save the boolean value specified by val in data($col$opt),
  861.         # adjust the columns, and redisplay the items
  862.         #
  863.         set oldVal $data($col$opt)
  864.         set data($col$opt) [expr {$val ? 1 : 0}]
  865.         adjustColumns $win $col 1
  866.         if {$data($col$opt) != $oldVal} {
  867.         redisplay $win
  868.         }
  869.     }
  870.  
  871.     -labelalign {
  872.         if {[string compare $val ""] == 0} {
  873.         #
  874.         # Unset data($col$opt)
  875.         #
  876.         set alignment [lindex $data(colList) [expr {2*$col + 1}]]
  877.         if {[info exists data($col$opt)]} {
  878.             unset data($col$opt)
  879.         }
  880.         } else {
  881.         #
  882.         # Save the properly formatted value of val in data($col$opt)
  883.         #
  884.         variable alignments
  885.         set val [mwutil::fullOpt "label alignment" $val $alignments]
  886.         set alignment $val
  887.         set data($col$opt) $val
  888.         }
  889.  
  890.         #
  891.         # Adjust the col'th label
  892.         #
  893.         set pixels [lindex $data(colList) [expr {2*$col}]]
  894.         if {$pixels == 0} {            ;# convention: dynamic width
  895.         if {$data($col-maxPixels) > 0 &&
  896.             $data($col-reqPixels) > $data($col-maxPixels)} {
  897.             set pixels $data($col-maxPixels)
  898.         }
  899.         }
  900.         if {$pixels != 0} {    
  901.         incr pixels $data($col-delta)
  902.         }
  903.         adjustLabel $win $col $pixels $alignment
  904.     }
  905.  
  906.     -labelbackground {
  907.         set w $data(hdrTxtFrLbl)$col
  908.         set optTail [string range $opt 6 end]    ;# remove the -label
  909.         if {[string compare $val ""] == 0} {
  910.         #
  911.         # Apply the value of the corresponding widget configuration
  912.         # option to the col'th label and its children (if any)
  913.         # and conditionally to the canvas displaying an up-
  914.         # or down-arrow, and unset data($col$opt)
  915.         #
  916.         $w configure -$optTail $data($opt)
  917.         foreach c [winfo children $w] {
  918.             $c configure -$optTail $data($opt)
  919.         }
  920.         if {$col == $data(arrowCol)} {
  921.             configCanvas $win
  922.         }
  923.         if {[info exists data($col$opt)]} {
  924.             unset data($col$opt)
  925.         }
  926.         } else {
  927.         #
  928.         # Apply the given value to the col'th label and its
  929.         # children (if any) and conditionally to the canvas
  930.         # displaying an up- or down-arrow, and save the
  931.         # properly formatted value of val in data($col$opt)
  932.         #
  933.         $w configure -$optTail $val
  934.         foreach c [winfo children $w] {
  935.             $c configure -$optTail $val
  936.         }
  937.         if {$col == $data(arrowCol)} {
  938.             configCanvas $win
  939.         }
  940.         set data($col$opt) [$w cget -$optTail]
  941.         }
  942.     }
  943.  
  944.     -labelborderwidth {
  945.         set w $data(hdrTxtFrLbl)$col
  946.         set optTail [string range $opt 6 end]    ;# remove the -label
  947.         if {[string compare $val ""] == 0} {
  948.         #
  949.         # Apply the value of the corresponding widget configuration
  950.         # option to the col'th label and unset data($col$opt)
  951.         #
  952.         configLabel $w -$optTail $data($opt)
  953.         if {[info exists data($col$opt)]} {
  954.             unset data($col$opt)
  955.         }
  956.         } else {
  957.         #
  958.         # Apply the given value to the col'th label and save the
  959.         # properly formatted value of val in data($col$opt)
  960.         #
  961.         configLabel $w -$optTail $val
  962.         set data($col$opt) [$w cget -$optTail]
  963.         }
  964.  
  965.         #
  966.         # Adjust the columns (including the height of the header frame)
  967.         #
  968.         adjustColumns $win l$col 1
  969.     }
  970.  
  971.     -labelcommand -
  972.     -name -
  973.     -sortcommand {
  974.         if {[string compare $val ""] == 0} {
  975.         if {[info exists data($col$opt)]} {
  976.             unset data($col$opt)
  977.         }
  978.         } else {
  979.         set data($col$opt) $val
  980.         }
  981.     }
  982.  
  983.     -labelfont {
  984.         set w $data(hdrTxtFrLbl)$col
  985.         set optTail [string range $opt 6 end]    ;# remove the -label
  986.         if {[string compare $val ""] == 0} {
  987.         #
  988.         # Apply the value of the corresponding widget
  989.         # configuration option to the col'th label and
  990.         # its children (if any), and unset data($col$opt)
  991.         #
  992.         $w configure -$optTail $data($opt)
  993.         foreach c [winfo children $w] {
  994.             $c configure -$optTail $data($opt)
  995.         }
  996.         if {[info exists data($col$opt)]} {
  997.             unset data($col$opt)
  998.         }
  999.         } else {
  1000.         #
  1001.         # Apply the given value to the col'th label and
  1002.         # its children (if any), and save the properly
  1003.         # formatted value of val in data($col$opt)
  1004.         #
  1005.         $w configure -$optTail $val
  1006.         foreach c [winfo children $w] {
  1007.             $c configure -$optTail $val
  1008.         }
  1009.         set data($col$opt) [$w cget -$optTail]
  1010.         }
  1011.  
  1012.         #
  1013.         # Conditionally resize the canvas displaying an up- or down-arrow
  1014.         # and adjust the columns (including the height of the header frame)
  1015.         #
  1016.         if {$col == $data(arrowCol)} {
  1017.         configCanvas $win
  1018.         drawArrows $win
  1019.         }
  1020.         adjustColumns $win l$col 1
  1021.     }
  1022.  
  1023.     -labelforeground {
  1024.         set w $data(hdrTxtFrLbl)$col
  1025.         set optTail [string range $opt 6 end]    ;# remove the -label
  1026.         if {[string compare $val ""] == 0} {
  1027.         #
  1028.         # Apply the value of the corresponding widget
  1029.         # configuration option to the col'th label and
  1030.         # its children (if any), and unset data($col$opt)
  1031.         #
  1032.         $w configure -$optTail $data($opt)
  1033.         foreach c [winfo children $w] {
  1034.             $c configure -$optTail $data($opt)
  1035.         }
  1036.         if {[info exists data($col$opt)]} {
  1037.             unset data($col$opt)
  1038.         }
  1039.         } else {
  1040.         #
  1041.         # Apply the given value to the col'th label and
  1042.         # its children (if any), and save the properly
  1043.         # formatted value of val in data($col$opt)
  1044.         #
  1045.         $w configure -$optTail $val
  1046.         foreach c [winfo children $w] {
  1047.             $c configure -$optTail $val
  1048.         }
  1049.         set data($col$opt) [$w cget -$optTail]
  1050.         }
  1051.     }
  1052.  
  1053.     -labelheight -
  1054.     -labelpady {
  1055.         set w $data(hdrTxtFrLbl)$col
  1056.         set optTail [string range $opt 6 end]    ;# remove the -label
  1057.         if {[string compare $val ""] == 0} {
  1058.         #
  1059.         # Apply the value of the corresponding widget configuration
  1060.         # option to the col'th label and unset data($col$opt)
  1061.         #
  1062.         configLabel $w -$optTail $data($opt)
  1063.         if {[info exists data($col$opt)]} {
  1064.             unset data($col$opt)
  1065.         }
  1066.         } else {
  1067.         #
  1068.         # Apply the given value to the col'th label and save the
  1069.         # properly formatted value of val in data($col$opt)
  1070.         #
  1071.         configLabel $w -$optTail $val
  1072.         set data($col$opt) [$w cget -$optTail]
  1073.         }
  1074.  
  1075.         #
  1076.         # Adjust the height of the header frame
  1077.         #
  1078.         adjustHeaderHeight $win
  1079.     }
  1080.  
  1081.     -labelimage {
  1082.         set w $data(hdrTxtFrLbl)$col
  1083.         if {[string compare $val ""] == 0} {
  1084.         foreach c [winfo children $w] {
  1085.             destroy $c
  1086.         }
  1087.         if {[info exists data($col$opt)]} {
  1088.             unset data($col$opt)
  1089.         }
  1090.         } else {
  1091.         if {![winfo exists $w.il]} {
  1092.             variable configSpecs
  1093.             variable configOpts
  1094.             foreach c [list $w.il $w.tl] {    ;# image and text labels
  1095.             #
  1096.             # Create the label $c
  1097.             #
  1098.             label $c -borderwidth 0 -height 0 \
  1099.                  -highlightthickness 0 -padx 0 \
  1100.                  -pady 0 -takefocus 0 -width 0
  1101.  
  1102.             #
  1103.             # Apply to it the current configuration options
  1104.             #
  1105.             foreach opt2 $configOpts {
  1106.                 if {[string compare \
  1107.                  [lindex $configSpecs($opt2) 2] c] == 0} {
  1108.                 $c configure $opt2 $data($opt2)
  1109.                 }
  1110.             }
  1111.             foreach opt2 {-background -font -foreground} {
  1112.                 $c configure $opt2 [$w cget $opt2]
  1113.             }
  1114.             foreach opt2 {-disabledforeground -state} {
  1115.                 catch {$c configure $opt2 [$w cget $opt2]}
  1116.             }
  1117.  
  1118.             #
  1119.             # Replace the binding tag Label with TablelistSubLabel
  1120.             # in the list of binding tags of the label $c
  1121.             #
  1122.             bindtags $c \
  1123.                  [lreplace [bindtags $c] 1 1 TablelistSubLabel]
  1124.             }
  1125.         }
  1126.  
  1127.         #
  1128.         # Display the specified image in the label
  1129.         # $w.il and save val in data($col$opt)
  1130.         #
  1131.         $w.il configure -image $val
  1132.         set data($col$opt) $val
  1133.         }
  1134.  
  1135.         #
  1136.         # Adjust the columns (including the height of the header frame)
  1137.         #
  1138.         adjustColumns $win l$col 1
  1139.     }
  1140.  
  1141.     -labelrelief {
  1142.         set w $data(hdrTxtFrLbl)$col
  1143.         set optTail [string range $opt 6 end]    ;# remove the -label
  1144.         if {[string compare $val ""] == 0} {
  1145.         #
  1146.         # Apply the value of the corresponding widget configuration
  1147.         # option to the col'th label and unset data($col$opt)
  1148.         #
  1149.         configLabel $w -$optTail $data($opt)
  1150.         if {[info exists data($col$opt)]} {
  1151.             unset data($col$opt)
  1152.         }
  1153.         } else {
  1154.         #
  1155.         # Apply the given value to the col'th label and save the
  1156.         # properly formatted value of val in data($col$opt)
  1157.         #
  1158.         configLabel $w -$optTail $val
  1159.         set data($col$opt) [$w cget -$optTail]
  1160.         }
  1161.     }
  1162.  
  1163.     -maxwidth {
  1164.         #
  1165.         # Save the properly formatted value of val in
  1166.         # data($col$opt), adjust the columns, and make
  1167.         # sure the items will be redisplayed at idle time
  1168.         #
  1169.         set val [format %d $val]    ;# integer check with error message
  1170.         set data($col$opt) $val
  1171.         if {$val > 0} {        ;# convention: max. width in characters
  1172.         set pixels [charsToPixels $win $data(-font) $val]
  1173.         } elseif {$val < 0} {    ;# convention: max. width in pixels
  1174.         set pixels [expr {(-1)*$val}]
  1175.         } else {            ;# convention: no max. width
  1176.         set pixels 0
  1177.         }
  1178.         set data($col-maxPixels) $pixels
  1179.         adjustColumns $win $col 1
  1180.         redisplayWhenIdle $win
  1181.     }
  1182.  
  1183.     -selectbackground -
  1184.     -selectforeground {
  1185.         set w $data(body)
  1186.         set tag $col$opt
  1187.         if {[string compare $val ""] == 0} {
  1188.         if {[info exists data($tag)]} {
  1189.             $w tag delete $tag
  1190.             unset data($tag)
  1191.         }
  1192.         } else {
  1193.         #
  1194.         # Configure the tag $tag in the body text widget
  1195.         #
  1196.         set optTail [string range $opt 7 end]    ;# remove the -select
  1197.         $w tag configure $tag -$optTail $val
  1198.         $w tag raise $tag select
  1199.  
  1200.         if {!$data($col-hide)} {
  1201.             #
  1202.             # Apply the tag to the elements of the given
  1203.             # column in all currently selected rows
  1204.             #
  1205.             set selRange [$w tag nextrange select 1.0]
  1206.             while {[llength $selRange] != 0} {
  1207.             set selStart [lindex $selRange 0]
  1208.             set selEnd [lindex $selRange 1]
  1209.  
  1210.             findCellTabs $win [expr {int($selStart)}] $col \
  1211.                      tabIdx1 tabIdx2
  1212.             $w tag add $tag $tabIdx1 $tabIdx2+1c
  1213.  
  1214.             set selRange [$w tag nextrange select $selEnd]
  1215.             }
  1216.         }
  1217.  
  1218.         #
  1219.         # Save the properly formatted value of val in data($tag)
  1220.         #
  1221.         set data($tag) [$w tag cget $tag -$optTail]
  1222.         }
  1223.     }
  1224.  
  1225.     -showarrow {
  1226.         #
  1227.         # Save the boolean value specified by val in data($col$opt) and
  1228.         # conditionally unmanage the canvas displaying an up- or down-arrow
  1229.         #
  1230.         set data($col$opt) [expr {$val ? 1 : 0}]
  1231.         if {!$data($col$opt) && $col == $data(arrowCol)} {
  1232.         place forget $data(hdrTxtFrCanv)
  1233.         set data(arrowCol) -1
  1234.         adjustColumns $win l$col 1
  1235.         }
  1236.     }
  1237.  
  1238.     -sortmode {
  1239.         #
  1240.         # Save the properly formatted value of val in data($col$opt)
  1241.         #
  1242.         variable sortModes
  1243.         set data($col$opt) [mwutil::fullOpt "sort mode" $val $sortModes]
  1244.     }
  1245.  
  1246.     -text {
  1247.         if {$data(isDisabled)} {
  1248.         return ""
  1249.         }
  1250.  
  1251.         #
  1252.         # Replace the column's contents in the internal list
  1253.         #
  1254.         set newItemList {}
  1255.         set row 0
  1256.         foreach item $data(itemList) text [lrange $val 0 $data(itemCount)] {
  1257.         set item [lreplace $item $col $col $text]
  1258.         lappend newItemList $item
  1259.         }
  1260.         set data(itemList) $newItemList
  1261.  
  1262.         #
  1263.         # Update the list variable if present
  1264.         #
  1265.         condUpdateListVar $win
  1266.  
  1267.         #
  1268.         # Adjust the columns and make sure the
  1269.         # items will be redisplayed at idle time
  1270.         #
  1271.         adjustColumns $win $col 1
  1272.         redisplayWhenIdle $win
  1273.     }
  1274.  
  1275.     -title {
  1276.         #
  1277.         # Save the given value in the corresponding
  1278.         # element of data(-columns) and adjust the columns
  1279.         #
  1280.         set idx [expr {3*$col + 1}]
  1281.         set data(-columns) [lreplace $data(-columns) $idx $idx $val]
  1282.         adjustColumns $win l$col 1
  1283.     }
  1284.  
  1285.     -width {
  1286.         #
  1287.         # Set up and adjust the columns, and make sure
  1288.         # the items will be redisplayed at idle time
  1289.         #
  1290.         set idx [expr {3*$col}]
  1291.         if {$val != [lindex $data(-columns) $idx]} {
  1292.         setupColumns $win [lreplace $data(-columns) $idx $idx $val] 0
  1293.         adjustColumns $win $col 1
  1294.         redisplayWhenIdle $win
  1295.         }
  1296.     }
  1297.     }
  1298. }
  1299.  
  1300. #------------------------------------------------------------------------------
  1301. # tablelist::doColCget
  1302. #
  1303. # Returns the value of the column configuration option opt for the col'th
  1304. # column of the tablelist widget win.
  1305. #------------------------------------------------------------------------------
  1306. proc tablelist::doColCget {col win opt} {
  1307.     upvar ::tablelist::ns${win}::data data
  1308.  
  1309.     switch -- $opt {
  1310.     -align {
  1311.         return [lindex $data(-columns) [expr {3*$col + 2}]]
  1312.     }
  1313.  
  1314.     -text {
  1315.         set result {}
  1316.         foreach item $data(itemList) {
  1317.         lappend result [lindex $item $col]
  1318.         }
  1319.         return $result
  1320.     }
  1321.  
  1322.     -title {
  1323.         return [lindex $data(-columns) [expr {3*$col + 1}]]
  1324.     }
  1325.  
  1326.     -width {
  1327.         return [lindex $data(-columns) [expr {3*$col}]]
  1328.     }
  1329.  
  1330.     default {
  1331.         if {[info exists data($col$opt)]} {
  1332.         return $data($col$opt)
  1333.         } else {
  1334.         return ""
  1335.         }
  1336.     }
  1337.     }
  1338. }
  1339.  
  1340. #------------------------------------------------------------------------------
  1341. # tablelist::doRowConfig
  1342. #
  1343. # Applies the value val of the row configuration option opt to the row'th row
  1344. # of the tablelist widget win.
  1345. #------------------------------------------------------------------------------
  1346. proc tablelist::doRowConfig {row win opt val} {
  1347.     upvar ::tablelist::ns${win}::data data
  1348.  
  1349.     set w $data(body)
  1350.  
  1351.     switch -- $opt {
  1352.     -background -
  1353.     -foreground {
  1354.         set item [lindex $data(itemList) $row]
  1355.         set key [lindex $item end]
  1356.         set tag $key$opt
  1357.  
  1358.         if {[string compare $val ""] == 0} {
  1359.         if {[info exists data($tag)]} {
  1360.             $w tag delete $tag
  1361.             unset data($tag)
  1362.             incr data(tagCount) -1
  1363.         }
  1364.         } else {
  1365.         #
  1366.         # Configure the tag $tag in the body text widget and
  1367.         # apply it to the given row if it is not selected
  1368.         #
  1369.         $w tag configure $tag $opt $val
  1370.         $w tag lower $tag disabled
  1371.         for {set col 0} {$col < $data(colCount)} {incr col} {
  1372.             if {[info exists data($key-$col$opt)]} {
  1373.             $w tag lower $key-$col$opt disabled
  1374.             }
  1375.         }
  1376.         set line [expr {$row + 1}]
  1377.         if {[lsearch -exact [$w tag names $line.0] select] < 0} {
  1378.             $w tag add $tag $line.0 $line.end
  1379.         }
  1380.  
  1381.         #
  1382.         # Save the properly formatted value of val in data($tag)
  1383.         #
  1384.         if {![info exists data($tag)]} {
  1385.             incr data(tagCount)
  1386.         }
  1387.         set data($tag) [$w tag cget $tag $opt]
  1388.         }
  1389.     }
  1390.  
  1391.     -font {
  1392.         #
  1393.         # Save the current cell fonts in a temporary array
  1394.         #
  1395.         set item [lindex $data(itemList) $row]
  1396.         set key [lindex $item end]
  1397.         for {set col 0} {$col < $data(colCount)} {incr col} {
  1398.         set oldCellFonts($col) [cellFont $win $key $col]
  1399.         }
  1400.  
  1401.         set tag $key$opt
  1402.         if {[string compare $val ""] == 0} {
  1403.         if {[info exists data($tag)]} {
  1404.             $w tag delete $tag
  1405.             unset data($tag)
  1406.             incr data(tagCount) -1
  1407.         }
  1408.         } else {
  1409.         #
  1410.         # Configure the tag $tag in the body text
  1411.         # widget and apply it to the given row
  1412.         #
  1413.         $w tag configure $tag $opt $val
  1414.         for {set col 0} {$col < $data(colCount)} {incr col} {
  1415.             if {[info exists data($key-$col$opt)]} {
  1416.             $w tag raise $key-$col$opt
  1417.             }
  1418.         }
  1419.         set line [expr {$row + 1}]
  1420.         $w tag add $tag $line.0 $line.end
  1421.  
  1422.         #
  1423.         # Save the properly formatted value of val in data($tag)
  1424.         #
  1425.         if {![info exists data($tag)]} {
  1426.             incr data(tagCount)
  1427.         }
  1428.         set data($tag) [$w tag cget $tag $opt]
  1429.         }
  1430.  
  1431.         set dispItem [strToDispStr $item]
  1432.         set colWidthsChanged 0
  1433.         set colList {}
  1434.         set line [expr {$row + 1}]
  1435.         set textIdx1 $line.1
  1436.         set col 0
  1437.         foreach text [lrange $dispItem 0 $data(lastCol)] \
  1438.             fmtCmdFlag $data(fmtCmdFlagList) \
  1439.             {pixels alignment} $data(colList) {
  1440.         if {$data($col-hide)} {
  1441.             incr col
  1442.             continue
  1443.         }
  1444.  
  1445.         #
  1446.         # Adjust the cell text and the image width
  1447.         #
  1448.         if {$fmtCmdFlag} {
  1449.             set text [uplevel #0 $data($col-formatcommand) \
  1450.                   [list [lindex $item $col]]]
  1451.             set text [strToDispStr $text]
  1452.         }
  1453.         if {[info exists data($key-$col-image)]} {
  1454.             set image $data($key-$col-image)
  1455.             set imageWidth [image width $image]
  1456.         } else {
  1457.             set image ""
  1458.             set imageWidth 0
  1459.         }
  1460.         set cellFont [cellFont $win $key $col]
  1461.         set workPixels $pixels
  1462.         if {$pixels == 0} {        ;# convention: dynamic width
  1463.             if {$data($col-maxPixels) > 0 &&
  1464.             $data($col-reqPixels) > $data($col-maxPixels)} {
  1465.             set workPixels $data($col-maxPixels)
  1466.             }
  1467.         }
  1468.         if {$workPixels != 0} {
  1469.             incr workPixels $data($col-delta)
  1470.         }
  1471.         adjustElem $win text imageWidth $cellFont \
  1472.                $workPixels $alignment $data(-snipstring)
  1473.  
  1474.         if {$row == $data(editRow) && $col == $data(editCol)} {
  1475.             #
  1476.             # Configure the edit window
  1477.             #
  1478.             variable editWin
  1479.             set name $data($col-editwindow)
  1480.             catch {
  1481.             $data(bodyFrEd) configure $editWin($name-fontOpt) \
  1482.                 [cellFont $win $key $col]
  1483.             }
  1484.         } else {
  1485.             #
  1486.             # Delete the old cell contents between the
  1487.             # two tabs, and insert the text and the image
  1488.             #
  1489.             set textIdx2 [$w search \t $textIdx1 $line.end]
  1490.             $w delete $textIdx1 $textIdx2
  1491.             insertElem $w $textIdx1 $text $image $imageWidth $alignment
  1492.         }
  1493.  
  1494.         if {$pixels == 0} {        ;# convention: dynamic width
  1495.             #
  1496.             # Check whether the width of the current column has changed
  1497.             #
  1498.             if {$workPixels > 0} {
  1499.             adjustElem $win text imageWidth $cellFont \
  1500.                    $pixels $alignment $data(-snipstring)
  1501.             }
  1502.             set textWidth [font measure $cellFont -displayof $win $text]
  1503.             set newElemWidth [expr {$imageWidth + $textWidth}]
  1504.             if {$newElemWidth > $data($col-elemWidth)} {
  1505.             set data($col-elemWidth) $newElemWidth
  1506.             set data($col-widestCount) 1
  1507.             if {$newElemWidth > $data($col-reqPixels)} {
  1508.                 set data($col-reqPixels) $newElemWidth
  1509.                 set colWidthsChanged 1
  1510.             }
  1511.             } else {
  1512.             set oldTextWidth [font measure $oldCellFonts($col) \
  1513.                       -displayof $win $text]
  1514.             set oldElemWidth [expr {$imageWidth + $oldTextWidth}]
  1515.             if {$oldElemWidth < $data($col-elemWidth) &&
  1516.                 $newElemWidth == $data($col-elemWidth)} {
  1517.                 incr data($col-widestCount)
  1518.             } elseif {$oldElemWidth == $data($col-elemWidth) &&
  1519.                   $newElemWidth < $oldElemWidth &&
  1520.                   [incr data($col-widestCount) -1] == 0} {
  1521.                 set colWidthsChanged 1
  1522.                 lappend colList $col
  1523.             }
  1524.             }
  1525.         }
  1526.  
  1527.         set textIdx1 [$w search \t $textIdx1 $line.end]+2c
  1528.         incr col
  1529.         }
  1530.  
  1531.         #
  1532.         # Adjust the columns if necessary
  1533.         #
  1534.         if {$colWidthsChanged} {
  1535.         adjustColumns $win $colList 1
  1536.         }
  1537.     }
  1538.  
  1539.     -selectable {
  1540.         set val [expr {$val ? 1 : 0}]
  1541.         set item [lindex $data(itemList) $row]
  1542.         set key [lindex $item end]
  1543.  
  1544.         if {$val} {
  1545.         if {[info exists data($key$opt)]} {
  1546.             unset data($key$opt)
  1547.         }
  1548.         } else {
  1549.         #
  1550.         # Set data($key$opt) to 0 and deselect the row
  1551.         #
  1552.         set data($key$opt) 0
  1553.         selectionSubCmd $win clear $row $row
  1554.         }
  1555.     }
  1556.  
  1557.     -selectbackground -
  1558.     -selectforeground {
  1559.         set item [lindex $data(itemList) $row]
  1560.         set key [lindex $item end]
  1561.         set tag $key$opt
  1562.  
  1563.         if {[string compare $val ""] == 0} {
  1564.         if {[info exists data($tag)]} {
  1565.             $w tag delete $tag
  1566.             unset data($tag)
  1567.         }
  1568.         } else {
  1569.         #
  1570.         # Configure the tag $tag in the body text widget
  1571.         # and apply it to the given row if it is selected
  1572.         #
  1573.         set optTail [string range $opt 7 end]    ;# remove the -select
  1574.         $w tag configure $tag -$optTail $val
  1575.         $w tag lower $tag disabled
  1576.         for {set col 0} {$col < $data(colCount)} {incr col} {
  1577.             if {[info exists data($key-$col$opt)]} {
  1578.             $w tag lower $key-$col$opt disabled
  1579.             }
  1580.         }
  1581.         set line [expr {$row + 1}]
  1582.         if {[lsearch -exact [$w tag names $line.0] select] >= 0} {
  1583.             $w tag add $tag $line.0 $line.end
  1584.         }
  1585.  
  1586.         #
  1587.         # Save the properly formatted value of val in data($tag)
  1588.         #
  1589.         set data($tag) [$w tag cget $tag -$optTail]
  1590.         }
  1591.     }
  1592.  
  1593.     -text {
  1594.         if {$data(isDisabled)} {
  1595.         return ""
  1596.         }
  1597.  
  1598.         set colWidthsChanged 0
  1599.         set colList {}
  1600.         set oldItem [lindex $data(itemList) $row]
  1601.         set key [lindex $oldItem end]
  1602.         set newItem [adjustItem $val $data(colCount)]
  1603.         set line [expr {$row + 1}]
  1604.         set textIdx1 $line.1
  1605.         set col 0
  1606.         foreach text [strToDispStr $newItem] \
  1607.             fmtCmdFlag $data(fmtCmdFlagList) \
  1608.             {pixels alignment} $data(colList) {
  1609.         if {$data($col-hide)} {
  1610.             incr col
  1611.             continue
  1612.         }
  1613.  
  1614.         #
  1615.         # Adjust the cell text and the image width
  1616.         #
  1617.         if {$fmtCmdFlag} {
  1618.             set text [uplevel #0 $data($col-formatcommand) \
  1619.                   [list [lindex $newItem $col]]]
  1620.             set text [strToDispStr $text]
  1621.         }
  1622.         if {[info exists data($key-$col-image)]} {
  1623.             set image $data($key-$col-image)
  1624.             set imageWidth [image width $image]
  1625.         } else {
  1626.             set image ""
  1627.             set imageWidth 0
  1628.         }
  1629.         set cellFont [cellFont $win $key $col]
  1630.         set workPixels $pixels
  1631.         if {$pixels == 0} {        ;# convention: dynamic width
  1632.             if {$data($col-maxPixels) > 0 &&
  1633.             $data($col-reqPixels) > $data($col-maxPixels)} {
  1634.             set workPixels $data($col-maxPixels)
  1635.             }
  1636.         }
  1637.         if {$workPixels != 0} {
  1638.             incr workPixels $data($col-delta)
  1639.         }
  1640.         adjustElem $win text imageWidth $cellFont \
  1641.                $workPixels $alignment $data(-snipstring)
  1642.  
  1643.         if {$row != $data(editRow) || $col != $data(editCol)} {
  1644.             #
  1645.             # Delete the old cell contents between the
  1646.             # two tabs, and insert the text and the image
  1647.             #
  1648.             set textIdx2 [$w search \t $textIdx1 $line.end]
  1649.             $w delete $textIdx1 $textIdx2
  1650.             insertElem $w $textIdx1 $text $image $imageWidth $alignment
  1651.         }
  1652.  
  1653.         if {$pixels == 0} {        ;# convention: dynamic width
  1654.             #
  1655.             # Check whether the width of the current column has changed
  1656.             #
  1657.             if {$workPixels > 0} {
  1658.             adjustElem $win text imageWidth $cellFont \
  1659.                    $pixels $alignment $data(-snipstring)
  1660.             }
  1661.             set textWidth [font measure $cellFont -displayof $win $text]
  1662.             set newElemWidth [expr {$imageWidth + $textWidth}]
  1663.             if {$newElemWidth > $data($col-elemWidth)} {
  1664.             set data($col-elemWidth) $newElemWidth
  1665.             set data($col-widestCount) 1
  1666.             if {$newElemWidth > $data($col-reqPixels)} {
  1667.                 set data($col-reqPixels) $newElemWidth
  1668.                 set colWidthsChanged 1
  1669.             }
  1670.             } else {
  1671.             set oldText [lindex $oldItem $col]
  1672.             if {$fmtCmdFlag} {
  1673.                 set oldText [uplevel #0 $data($col-formatcommand) \
  1674.                      [list $oldText]]
  1675.             }
  1676.             set oldText [strToDispStr $oldText]
  1677.             adjustElem $win oldText imageWidth $cellFont \
  1678.                    $pixels $alignment $data(-snipstring)
  1679.             set oldTextWidth \
  1680.                 [font measure $cellFont -displayof $win $oldText]
  1681.             set oldElemWidth [expr {$imageWidth + $oldTextWidth}]
  1682.             if {$oldElemWidth < $data($col-elemWidth) &&
  1683.                 $newElemWidth == $data($col-elemWidth)} {
  1684.                 incr data($col-widestCount)
  1685.             } elseif {$oldElemWidth == $data($col-elemWidth) &&
  1686.                   $newElemWidth < $oldElemWidth &&
  1687.                   [incr data($col-widestCount) -1] == 0} {
  1688.                 set colWidthsChanged 1
  1689.                 lappend colList $col
  1690.             }
  1691.             }
  1692.         }
  1693.  
  1694.         set textIdx1 [$w search \t $textIdx1 $line.end]+2c
  1695.         incr col
  1696.         }
  1697.  
  1698.         #
  1699.         # Replace the row contents in the list variable if present
  1700.         #
  1701.         if {$data(hasListVar)} {
  1702.         trace vdelete ::$data(-listvariable) wu $data(listVarTraceCmd)
  1703.         upvar #0 $data(-listvariable) var
  1704.         set var [lreplace $var $row $row $newItem]
  1705.         trace variable ::$data(-listvariable) wu $data(listVarTraceCmd)
  1706.         }
  1707.  
  1708.         #
  1709.         # Replace the row contents in the internal list
  1710.         #
  1711.         lappend newItem [lindex $oldItem end]
  1712.         set data(itemList) [lreplace $data(itemList) $row $row $newItem]
  1713.  
  1714.         #
  1715.         # Adjust the columns if necessary
  1716.         #
  1717.         if {$colWidthsChanged} {
  1718.         adjustColumns $win $colList 1
  1719.         }
  1720.     }
  1721.     }
  1722. }
  1723.  
  1724. #------------------------------------------------------------------------------
  1725. # tablelist::doRowCget
  1726. #
  1727. # Returns the value of the row configuration option opt for the row'th row of
  1728. # the tablelist widget win.
  1729. #------------------------------------------------------------------------------
  1730. proc tablelist::doRowCget {row win opt} {
  1731.     upvar ::tablelist::ns${win}::data data
  1732.  
  1733.     #
  1734.     # Return the value of the specified row configuration option
  1735.     #
  1736.     switch -- $opt {
  1737.     -text {
  1738.         set item [lindex $data(itemList) $row]
  1739.         return [lrange $item 0 $data(lastCol)]
  1740.     }
  1741.  
  1742.     -selectable {
  1743.         set item [lindex $data(itemList) $row]
  1744.         set key [lindex $item end]
  1745.         if {[info exists data($key$opt)]} {
  1746.         return $data($key$opt)
  1747.         } else {
  1748.         return 1
  1749.         }
  1750.     }
  1751.  
  1752.     default {
  1753.         set item [lindex $data(itemList) $row]
  1754.         set key [lindex $item end]
  1755.         if {[info exists data($key$opt)]} {
  1756.         return $data($key$opt)
  1757.         } else {
  1758.         return ""
  1759.         }
  1760.     }
  1761.     }
  1762. }
  1763.  
  1764. #------------------------------------------------------------------------------
  1765. # tablelist::doCellConfig
  1766. #
  1767. # Applies the value val of the cell configuration option opt to the cell
  1768. # row,col of the tablelist widget win.
  1769. #------------------------------------------------------------------------------
  1770. proc tablelist::doCellConfig {row col win opt val} {
  1771.     upvar ::tablelist::ns${win}::data data
  1772.  
  1773.     set w $data(body)
  1774.  
  1775.     switch -- $opt {
  1776.     -background -
  1777.     -foreground {
  1778.         set item [lindex $data(itemList) $row]
  1779.         set key [lindex $item end]
  1780.         set tag $key-$col$opt
  1781.  
  1782.         if {[string compare $val ""] == 0} {
  1783.         if {[info exists data($tag)]} {
  1784.             $w tag delete $tag
  1785.             unset data($tag)
  1786.             incr data(tagCount) -1
  1787.         }
  1788.         } else {
  1789.         #
  1790.         # Configure the tag $tag in the body text widget
  1791.         #
  1792.         $w tag configure $tag $opt $val
  1793.         $w tag lower $tag disabled
  1794.  
  1795.         if {!$data($col-hide)} {
  1796.             #
  1797.             # Apply the tag to the given cell if it is not selected
  1798.             #
  1799.             set line [expr {$row + 1}]
  1800.             if {[lsearch -exact [$w tag names $line.0] select] < 0} {
  1801.             findCellTabs $win $line $col tabIdx1 tabIdx2
  1802.             $w tag add $tag $tabIdx1 $tabIdx2+1c
  1803.             }
  1804.         }
  1805.  
  1806.         #
  1807.         # Save the properly formatted value of val in data($tag)
  1808.         #
  1809.         if {![info exists data($tag)]} {
  1810.             incr data(tagCount)
  1811.         }
  1812.         set data($tag) [$w tag cget $tag $opt]
  1813.         }
  1814.     }
  1815.  
  1816.     -editable {
  1817.         #
  1818.         # Save the boolean value specified by val in data($key-$col$opt)
  1819.         #
  1820.         set item [lindex $data(itemList) $row]
  1821.         set key [lindex $item end]
  1822.         set data($key-$col$opt) [expr {$val ? 1 : 0}]
  1823.     }
  1824.  
  1825.     -font {
  1826.         #
  1827.         # Save the current cell font
  1828.         #
  1829.         set item [lindex $data(itemList) $row]
  1830.         set key [lindex $item end]
  1831.         set oldCellFont [cellFont $win $key $col]
  1832.  
  1833.         set tag $key-$col$opt
  1834.         if {[string compare $val ""] == 0} {
  1835.         if {[info exists data($tag)]} {
  1836.             $w tag delete $tag
  1837.             unset data($tag)
  1838.             incr data(tagCount) -1
  1839.         }
  1840.         } else {
  1841.         #
  1842.         # Configure the tag $tag in the body text widget
  1843.         #
  1844.         $w tag configure $tag $opt $val
  1845.         $w tag raise $tag
  1846.  
  1847.         if {!$data($col-hide)} {
  1848.             #
  1849.             # Apply the tag to the given cell
  1850.             #
  1851.             findCellTabs $win [expr {$row + 1}] $col tabIdx1 tabIdx2
  1852.             $w tag add $tag $tabIdx1 $tabIdx2+1c
  1853.         }
  1854.  
  1855.         #
  1856.         # Save the properly formatted value of val in data($tag)
  1857.         #
  1858.         if {![info exists data($tag)]} {
  1859.             incr data(tagCount)
  1860.         }
  1861.         set data($tag) [$w tag cget $tag $opt]
  1862.         }
  1863.  
  1864.         set pixels [lindex $data(colList) [expr {2*$col}]]
  1865.         set workPixels $pixels
  1866.         if {$pixels == 0} {            ;# convention: dynamic width
  1867.         if {$data($col-maxPixels) > 0 &&
  1868.             $data($col-reqPixels) > $data($col-maxPixels)} {
  1869.             set workPixels $data($col-maxPixels)
  1870.         }
  1871.         }
  1872.         if {$workPixels != 0} {
  1873.         incr workPixels $data($col-delta)
  1874.         }
  1875.         set alignment [lindex $data(colList) [expr {2*$col + 1}]]
  1876.  
  1877.         #
  1878.         # Adjust the cell text and the image width
  1879.         #
  1880.         set text [lindex $item $col]
  1881.         if {[info exists data($col-formatcommand)]} {
  1882.         set text [uplevel #0 $data($col-formatcommand) [list $text]]
  1883.         }
  1884.         set text [strToDispStr $text]
  1885.         if {[info exists data($key-$col-image)]} {
  1886.         set image $data($key-$col-image)
  1887.         set imageWidth [image width $image]
  1888.         } else {
  1889.         set image ""
  1890.         set imageWidth 0
  1891.         }
  1892.         set cellFont [cellFont $win $key $col]
  1893.         adjustElem $win text imageWidth $cellFont \
  1894.                $workPixels $alignment $data(-snipstring)
  1895.  
  1896.         if {!$data($col-hide)} {
  1897.         if {$row == $data(editRow) && $col == $data(editCol)} {
  1898.             #
  1899.             # Configure the edit window
  1900.             #
  1901.             variable editWin
  1902.             set name $data($col-editwindow)
  1903.             catch {
  1904.             $data(bodyFrEd) configure $editWin($name-fontOpt) \
  1905.                 [cellFont $win $key $col]
  1906.             }
  1907.         } else {
  1908.             #
  1909.             # Delete the old cell contents between the
  1910.             # two tabs, and insert the text and the image
  1911.             #
  1912.             findCellTabs $win [expr {$row + 1}] $col tabIdx1 tabIdx2
  1913.             $w delete $tabIdx1+1c $tabIdx2
  1914.             insertElem $w $tabIdx1+1c $text $image $imageWidth \
  1915.                    $alignment
  1916.         }
  1917.         }
  1918.  
  1919.         #
  1920.         # Adjust the columns if necessary
  1921.         #
  1922.         if {$pixels == 0} {            ;# convention: dynamic width
  1923.         if {$workPixels > 0} {
  1924.             adjustElem $win text imageWidth $cellFont \
  1925.                    $pixels $alignment $data(-snipstring)
  1926.         }
  1927.         set textWidth [font measure $cellFont -displayof $win $text]
  1928.         set newElemWidth [expr {$imageWidth + $textWidth}]
  1929.         if {$newElemWidth > $data($col-elemWidth)} {
  1930.             set data($col-elemWidth) $newElemWidth
  1931.             set data($col-widestCount) 1
  1932.             if {$newElemWidth > $data($col-reqPixels)} {
  1933.             set data($col-reqPixels) $newElemWidth
  1934.             adjustColumns $win {} 1
  1935.             }
  1936.         } else {
  1937.             set oldTextWidth \
  1938.             [font measure $oldCellFont -displayof $win $text]
  1939.             set oldElemWidth [expr {$imageWidth + $oldTextWidth}]
  1940.             if {$oldElemWidth < $data($col-elemWidth) &&
  1941.             $newElemWidth == $data($col-elemWidth)} {
  1942.             incr data($col-widestCount)
  1943.             } elseif {$oldElemWidth == $data($col-elemWidth) &&
  1944.                   $newElemWidth < $oldElemWidth &&
  1945.                   [incr data($col-widestCount) -1] == 0} {
  1946.             adjustColumns $win $col 1
  1947.             }
  1948.         }
  1949.         }
  1950.     }
  1951.  
  1952.     -image {
  1953.         if {$data(isDisabled)} {
  1954.         return ""
  1955.         }
  1956.  
  1957.         set pixels [lindex $data(colList) [expr {2*$col}]]
  1958.         set workPixels $pixels
  1959.         if {$pixels == 0} {            ;# convention: dynamic width
  1960.         if {$data($col-maxPixels) > 0 &&
  1961.             $data($col-reqPixels) > $data($col-maxPixels)} {
  1962.             set workPixels $data($col-maxPixels)
  1963.         }
  1964.         }
  1965.         if {$workPixels != 0} {
  1966.         incr workPixels $data($col-delta)
  1967.         }
  1968.         set alignment [lindex $data(colList) [expr {2*$col + 1}]]
  1969.  
  1970.         #
  1971.         # Adjust the cell text and the image width
  1972.         #
  1973.         set item [lindex $data(itemList) $row]
  1974.         set text [lindex $item $col]
  1975.         if {[info exists data($col-formatcommand)]} {
  1976.         set text [uplevel #0 $data($col-formatcommand) [list $text]]
  1977.         }
  1978.         set text [strToDispStr $text]
  1979.         set oldText $text            ;# will be needed later
  1980.         set image $val
  1981.         if {[string compare $image ""] == 0} {
  1982.         set imageWidth 0
  1983.         } else {
  1984.         set imageWidth [image width $image]
  1985.         }
  1986.         set key [lindex $item end]
  1987.         set cellFont [cellFont $win $key $col]
  1988.         adjustElem $win text imageWidth $cellFont \
  1989.                $workPixels $alignment $data(-snipstring)
  1990.  
  1991.         if {!$data($col-hide) &&
  1992.         !($row == $data(editRow) && $col == $data(editCol))} {
  1993.         #
  1994.         # Delete the old cell contents between the
  1995.         # two tabs, and insert the text and the image
  1996.         #
  1997.         findCellTabs $win [expr {$row + 1}] $col tabIdx1 tabIdx2
  1998.         $w delete $tabIdx1+1c $tabIdx2
  1999.         insertElem $w $tabIdx1+1c $text $image $imageWidth $alignment
  2000.         }
  2001.  
  2002.         #
  2003.         # Save the old image width
  2004.         #
  2005.         set name $key-$col$opt
  2006.         if {[info exists data($name)]} {
  2007.         set oldImageWidth [image width $data($name)]
  2008.         } else {
  2009.         set oldImageWidth 0
  2010.         }
  2011.  
  2012.         #
  2013.         # Delete data($name) or save the specified value in it
  2014.         #
  2015.         if {[string compare $val ""] == 0} {
  2016.         if {[info exists data($name)]} {
  2017.             unset data($name)
  2018.             incr data(imgCount) -1
  2019.         }
  2020.         } else {
  2021.         if {![info exists data($name)]} {
  2022.             incr data(imgCount)
  2023.         }
  2024.         set data($name) $val
  2025.         }
  2026.  
  2027.         #
  2028.         # Adjust the columns if necessary
  2029.         #
  2030.         if {$pixels == 0} {            ;# convention: dynamic width
  2031.         if {$workPixels > 0} {
  2032.             adjustElem $win text imageWidth $cellFont \
  2033.                    $pixels $alignment $data(-snipstring)
  2034.         }
  2035.         set textWidth [font measure $cellFont -displayof $win $text]
  2036.         set newElemWidth [expr {$imageWidth + $textWidth}]
  2037.         if {$newElemWidth > $data($col-elemWidth)} {
  2038.             set data($col-elemWidth) $newElemWidth
  2039.             set data($col-widestCount) 1
  2040.             if {$newElemWidth > $data($col-reqPixels)} {
  2041.             set data($col-reqPixels) $newElemWidth
  2042.             adjustColumns $win {} 1
  2043.             }
  2044.         } else {
  2045.             adjustElem $win oldText oldImageWidth $cellFont \
  2046.                    $pixels $alignment $data(-snipstring)
  2047.             set oldTextWidth \
  2048.             [font measure $cellFont -displayof $win $oldText]
  2049.             set oldElemWidth [expr {$oldImageWidth + $oldTextWidth}]
  2050.             if {$oldElemWidth < $data($col-elemWidth) &&
  2051.             $newElemWidth == $data($col-elemWidth)} {
  2052.             incr data($col-widestCount)
  2053.             } elseif {$oldElemWidth == $data($col-elemWidth) &&
  2054.                   $newElemWidth < $oldElemWidth &&
  2055.                   [incr data($col-widestCount) -1] == 0} {
  2056.             adjustColumns $win $col 1
  2057.             }
  2058.         }
  2059.         }
  2060.     }
  2061.  
  2062.     -selectbackground -
  2063.     -selectforeground {
  2064.         set item [lindex $data(itemList) $row]
  2065.         set key [lindex $item end]
  2066.         set tag $key-$col$opt
  2067.  
  2068.         if {[string compare $val ""] == 0} {
  2069.         if {[info exists data($tag)]} {
  2070.             $w tag delete $tag
  2071.             unset data($tag)
  2072.         }
  2073.         } else {
  2074.         #
  2075.         # Configure the tag $tag in the body text widget
  2076.         #
  2077.         set optTail [string range $opt 7 end]    ;# remove the -select
  2078.         $w tag configure $tag -$optTail $val
  2079.         $w tag lower $tag disabled
  2080.  
  2081.         if {!$data($col-hide)} {
  2082.             #
  2083.             # Apply the tag to the given cell if it is selected
  2084.             #
  2085.             set line [expr {$row + 1}]
  2086.             if {[lsearch -exact [$w tag names $line.0] select] >= 0} {
  2087.             findCellTabs $win $line $col tabIdx1 tabIdx2
  2088.             $w tag add $tag $tabIdx1 $tabIdx2+1c
  2089.             }
  2090.         }
  2091.  
  2092.         #
  2093.         # Save the properly formatted value of val in data($tag)
  2094.         #
  2095.         set data($tag) [$w tag cget $tag -$optTail]
  2096.         }
  2097.     }
  2098.  
  2099.     -text {
  2100.         if {$data(isDisabled)} {
  2101.         return ""
  2102.         }
  2103.  
  2104.         set pixels [lindex $data(colList) [expr {2*$col}]]
  2105.         set workPixels $pixels
  2106.         if {$pixels == 0} {            ;# convention: dynamic width
  2107.         if {$data($col-maxPixels) > 0 &&
  2108.             $data($col-reqPixels) > $data($col-maxPixels)} {
  2109.             set workPixels $data($col-maxPixels)
  2110.         }
  2111.         }
  2112.         if {$workPixels != 0} {
  2113.         incr workPixels $data($col-delta)
  2114.         }
  2115.         set alignment [lindex $data(colList) [expr {2*$col + 1}]]
  2116.  
  2117.         #
  2118.         # Adjust the cell text and the image width
  2119.         #
  2120.         set text $val
  2121.         set fmtCmdFlag [info exists data($col-formatcommand)]
  2122.         if {$fmtCmdFlag} {
  2123.         set text [uplevel #0 $data($col-formatcommand) [list $text]]
  2124.         }
  2125.         set text [strToDispStr $text]
  2126.         set oldItem [lindex $data(itemList) $row]
  2127.         set key [lindex $oldItem end]
  2128.         if {[info exists data($key-$col-image)]} {
  2129.         set image $data($key-$col-image)
  2130.         set imageWidth [image width $image]
  2131.         } else {
  2132.         set image ""
  2133.         set imageWidth 0
  2134.         }
  2135.         set cellFont [cellFont $win $key $col]
  2136.         adjustElem $win text imageWidth $cellFont \
  2137.                $workPixels $alignment $data(-snipstring)
  2138.  
  2139.         if {!$data($col-hide) &&
  2140.         !($row == $data(editRow) && $col == $data(editCol))} {
  2141.         #
  2142.         # Delete the old cell contents between the
  2143.         # two tabs, and insert the text and the image
  2144.         #
  2145.         findCellTabs $win [expr {$row + 1}] $col tabIdx1 tabIdx2
  2146.         $w delete $tabIdx1+1c $tabIdx2
  2147.         insertElem $w $tabIdx1+1c $text $image $imageWidth $alignment
  2148.         }
  2149.  
  2150.         #
  2151.         # Replace the cell contents in the internal list
  2152.         #
  2153.         set newItem [lreplace $oldItem $col $col $val]
  2154.         set data(itemList) [lreplace $data(itemList) $row $row $newItem]
  2155.  
  2156.         #
  2157.         # Replace the cell contents in the list variable if present
  2158.         #
  2159.         if {$data(hasListVar)} {
  2160.         trace vdelete ::$data(-listvariable) wu $data(listVarTraceCmd)
  2161.         upvar #0 $data(-listvariable) var
  2162.         set var [lreplace $var $row $row \
  2163.              [lrange $newItem 0 $data(lastCol)]]
  2164.         trace variable ::$data(-listvariable) wu $data(listVarTraceCmd)
  2165.         }
  2166.  
  2167.         #
  2168.         # Adjust the columns if necessary
  2169.         #
  2170.         if {$pixels == 0} {            ;# convention: dynamic width
  2171.         if {$workPixels > 0} {
  2172.             adjustElem $win text imageWidth $cellFont \
  2173.                    $pixels $alignment $data(-snipstring)
  2174.         }
  2175.         set textWidth [font measure $cellFont -displayof $win $text]
  2176.         set newElemWidth [expr {$imageWidth + $textWidth}]
  2177.         if {$newElemWidth > $data($col-elemWidth)} {
  2178.             set data($col-elemWidth) $newElemWidth
  2179.             set data($col-widestCount) 1
  2180.             if {$newElemWidth > $data($col-reqPixels)} {
  2181.             set data($col-reqPixels) $newElemWidth
  2182.             adjustColumns $win {} 1
  2183.             }
  2184.         } else {
  2185.             set oldText [lindex $oldItem $col]
  2186.             if {$fmtCmdFlag} {
  2187.             set oldText [uplevel #0 $data($col-formatcommand) \
  2188.                      [list $oldText]]
  2189.             }
  2190.             set oldText [strToDispStr $oldText]
  2191.             adjustElem $win oldText imageWidth $cellFont \
  2192.                    $pixels $alignment $data(-snipstring)
  2193.             set oldTextWidth \
  2194.             [font measure $cellFont -displayof $win $oldText]
  2195.             set oldElemWidth [expr {$imageWidth + $oldTextWidth}]
  2196.             if {$oldElemWidth < $data($col-elemWidth) &&
  2197.             $newElemWidth == $data($col-elemWidth)} {
  2198.             incr data($col-widestCount)
  2199.             } elseif {$oldElemWidth == $data($col-elemWidth) &&
  2200.                   $newElemWidth < $oldElemWidth &&
  2201.                   [incr data($col-widestCount) -1] == 0} {
  2202.             adjustColumns $win $col 1
  2203.             }
  2204.         }
  2205.         }
  2206.     }
  2207.     }
  2208. }
  2209.  
  2210. #------------------------------------------------------------------------------
  2211. # tablelist::doCellCget
  2212. #
  2213. # Returns the value of the cell configuration option opt for the cell row,col
  2214. # of the tablelist widget win.
  2215. #------------------------------------------------------------------------------
  2216. proc tablelist::doCellCget {row col win opt} {
  2217.     upvar ::tablelist::ns${win}::data data
  2218.  
  2219.     #
  2220.     # Return the value of the specified cell configuration option
  2221.     #
  2222.     switch -- $opt {
  2223.     -editable {
  2224.         return [isCellEditable $win $row $col]
  2225.     }
  2226.  
  2227.     -text {
  2228.         set item [lindex $data(itemList) $row]
  2229.         return [lindex $item $col]
  2230.     }
  2231.  
  2232.     default {
  2233.         set item [lindex $data(itemList) $row]
  2234.         set key [lindex $item end]
  2235.         if {[info exists data($key-$col$opt)]} {
  2236.         return $data($key-$col$opt)
  2237.         } else {
  2238.         return ""
  2239.         }
  2240.     }
  2241.     }
  2242. }
  2243.  
  2244. #------------------------------------------------------------------------------
  2245. # tablelist::makeListVar
  2246. #
  2247. # Arranges for the global variable specified by varName to become the list
  2248. # variable associated with the tablelist widget win.
  2249. #------------------------------------------------------------------------------
  2250. proc tablelist::makeListVar {win varName} {
  2251.     upvar ::tablelist::ns${win}::data data
  2252.  
  2253.     if {[string compare $varName ""] == 0} {
  2254.     #
  2255.     # If there is an old list variable associated with the
  2256.     # widget then remove the trace set on this variable
  2257.     #
  2258.     if {$data(hasListVar)} {
  2259.         synchronize $win
  2260.         trace vdelete ::$data(-listvariable) wu $data(listVarTraceCmd)
  2261.     }
  2262.     return ""
  2263.     }
  2264.  
  2265.     #
  2266.     # The list variable may be an array element but must not be an array
  2267.     #
  2268.     if {![regexp {^(.*)\((.*)\)$} $varName dummy name1 name2]} {
  2269.     if {[array exists ::$varName]} {
  2270.         return -code error "variable \"$varName\" is array"
  2271.     }
  2272.     set name1 $varName
  2273.     set name2 ""
  2274.     }
  2275.  
  2276.     if {[info exists ::$varName]} {
  2277.     #
  2278.     # Invoke the trace procedure associated with the new list variable
  2279.     #
  2280.     listVarTrace $win $name1 $name2 w
  2281.     } else {
  2282.     #
  2283.     # Set ::$varName according to the value of data(itemList)
  2284.     #
  2285.     set ::$varName {}
  2286.     foreach item $data(itemList) {
  2287.         lappend ::$varName [lrange $item 0 $data(lastCol)]
  2288.     }
  2289.     }
  2290.  
  2291.     #
  2292.     # If there is an old list variable associated with the
  2293.     # widget then remove the trace set on this variable,
  2294.     # and in any case set a trace on the new list variable
  2295.     #
  2296.     if {$data(hasListVar)} {
  2297.     trace vdelete ::$data(-listvariable) wu $data(listVarTraceCmd)
  2298.     }
  2299.     trace variable ::$varName wu $data(listVarTraceCmd)
  2300. }
  2301.